package engine.render;

import engine.render.buffer.TriBuffer;
import math.vector.vec3f;

public class FrusCuller 
{
    
    private vec3f prevPosCamera;
    private vec3f prevDirCamera;
    
    public FrusCuller() 
    {
        prevPosCamera = new vec3f();
        prevDirCamera = new vec3f();
    }
    
    public void cull(TriBuffer dim3, Frustum frus, GLManager glManager) 
    {
        prevPosCamera = frus.getPosCamera();
        prevDirCamera = frus.getDirCamera();
        frus.updateMinimal(glManager);
        if (!frus.getPosCamera().isCloseTo(prevPosCamera) || !frus.getDirCamera().isCloseTo(prevDirCamera)) 
        {
            frus.recalculate(glManager);
        }
        cullTris(dim3, frus);
    }
    
    private void cullTris(TriBuffer dim3, Frustum frus) 
    {
        for (int i = 0; i < dim3.nTrisSent(); i++) 
        {
            if (dim3.tris[i] != null) 
            {
                for (int k = 0; k < 6; k++) 
                {
                    if (
                            frus.normals[k].x * (dim3.tris[i].verts[0].x - frus.planePts[k].x) 
                            + frus.normals[k].y * (dim3.tris[i].verts[0].y - frus.planePts[k].y)
                            + frus.normals[k].z * (dim3.tris[i].verts[0].z - frus.planePts[k].z)
                            < 0.0f) 
                    {
                        if (
                                frus.normals[k].x * (dim3.tris[i].verts[1].x - frus.planePts[k].x) 
                                + frus.normals[k].y * (dim3.tris[i].verts[1].y - frus.planePts[k].y)
                                + frus.normals[k].z * (dim3.tris[i].verts[1].z - frus.planePts[k].z)
                                < 0.0f) 
                        {
                            if (
                                    frus.normals[k].x * (dim3.tris[i].verts[2].x - frus.planePts[k].x) 
                                    + frus.normals[k].y * (dim3.tris[i].verts[2].y - frus.planePts[k].y)
                                    + frus.normals[k].z * (dim3.tris[i].verts[2].z - frus.planePts[k].z)
                                    < 0.0f) 
                            {
                                dim3.tris[i] = null;
                                break;
                            } // END IF : THIRD VERTEX CHECK
                        } // END IF : SECOND VERTEX CHECK
                    } // END IF : FIRST VERTEX CHECK
                } // END FOR : PLANES ITERATION
            } // END IF : NULL CHECK
        } // END FOR : TRI ARRAY ITERATION
        
    } // END METHOD : void cullTris(TriBuffer, Frustum)
    
}
